package com.campuscarbooking.api.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class RabbitMQConfig {

    // Queue names
    public static final String RESERVATION_NOTIFICATION_QUEUE = "reservation.notification.queue";
    public static final String SCHEDULE_UPDATE_QUEUE = "schedule.update.queue";
    public static final String CACHE_CONSISTENCY_QUEUE = "cache.consistency.queue";
    public static final String CACHE_DELAY_QUEUE = "cache.delay.queue";

    // Exchange names
    public static final String BOOKING_EXCHANGE = "booking.exchange";
    public static final String CACHE_CONSISTENCY_EXCHANGE = "cache.consistency.exchange";
    public static final String CACHE_DELAY_EXCHANGE = "cache.delay.exchange";

    // Routing keys
    public static final String RESERVATION_NOTIFICATION_ROUTING_KEY = "reservation.notification";
    public static final String SCHEDULE_UPDATE_ROUTING_KEY = "schedule.update";
    public static final String CACHE_CONSISTENCY_ROUTING_KEY = "cache.consistency";
    public static final String CACHE_DELAY_ROUTING_KEY = "cache.delay";

    // Delay time in milliseconds
    public static final int CACHE_DELAY_TIME = 1000; // 1 second

    @Bean
    public Queue reservationNotificationQueue() {
        return QueueBuilder.durable(RESERVATION_NOTIFICATION_QUEUE).build();
    }

    @Bean
    public Queue scheduleUpdateQueue() {
        return QueueBuilder.durable(SCHEDULE_UPDATE_QUEUE).build();
    }

    @Bean
    public Queue cacheConsistencyQueue() {
        return QueueBuilder.durable(CACHE_CONSISTENCY_QUEUE).build();
    }

    @Bean
    public Queue cacheDelayQueue() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-dead-letter-exchange", CACHE_CONSISTENCY_EXCHANGE);
        args.put("x-dead-letter-routing-key", CACHE_CONSISTENCY_ROUTING_KEY);
        args.put("x-message-ttl", CACHE_DELAY_TIME);
        return QueueBuilder.durable(CACHE_DELAY_QUEUE)
                .withArguments(args)
                .build();
    }

    @Bean
    public TopicExchange bookingExchange() {
        return ExchangeBuilder.topicExchange(BOOKING_EXCHANGE).durable(true).build();
    }

    @Bean
    public TopicExchange cacheConsistencyExchange() {
        return ExchangeBuilder.topicExchange(CACHE_CONSISTENCY_EXCHANGE).durable(true).build();
    }

    @Bean
    public DirectExchange cacheDelayExchange() {
        return ExchangeBuilder.directExchange(CACHE_DELAY_EXCHANGE).durable(true).build();
    }

    @Bean
    public Binding reservationNotificationBinding() {
        return BindingBuilder
                .bind(reservationNotificationQueue())
                .to(bookingExchange())
                .with(RESERVATION_NOTIFICATION_ROUTING_KEY);
    }

    @Bean
    public Binding scheduleUpdateBinding() {
        return BindingBuilder
                .bind(scheduleUpdateQueue())
                .to(bookingExchange())
                .with(SCHEDULE_UPDATE_ROUTING_KEY);
    }

    @Bean
    public Binding cacheConsistencyBinding() {
        return BindingBuilder
                .bind(cacheConsistencyQueue())
                .to(cacheConsistencyExchange())
                .with(CACHE_CONSISTENCY_ROUTING_KEY);
    }

    @Bean
    public Binding cacheDelayBinding() {
        return BindingBuilder
                .bind(cacheDelayQueue())
                .to(cacheDelayExchange())
                .with(CACHE_DELAY_ROUTING_KEY);
    }

    @Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(jsonMessageConverter());
        return rabbitTemplate;
    }
} 